//! Adapter to create integer types with +-infinity, and not a value
/*! This class is used internally in counted date/time representations.
 *  It adds the floating point like features of infinities and
 *  not a number. It also provides mathmatical operations with
 *  consideration to special values following these rules:
 *@code
 *  +infinity  -  infinity  == Not A Number (NAN)
 *   infinity  *  non-zero  == infinity
 *   infinity  *  zero      == NAN
 *  +infinity  * -integer   == -infinity
 *   infinity  /  infinity  == NAN
 *   infinity  *  infinity  == infinity 
 *@endcode 
 */
template<typename int_type_>
class int_adapter {
public:
  typedef int_type_ int_type;
  int_adapter(int_type v) :
    value_(v)
  {}
  static bool has_infinity()
  {
    return true;
  }
  static __const__ int_adapter pos_infinity()
  {
    return (::std::numeric_limits<int_type>::max)();
  }
  static __const__ int_adapter neg_infinity()
  {
    return (::std::numeric_limits<int_type>::min)();
  }
  static __const__ int_adapter not_a_number()
  {
    return (::std::numeric_limits<int_type>::max)()-1;
  }
  static int_adapter max ()
  {
    return (::std::numeric_limits<int_type>::max)()-2;
  }
  static int_adapter min ()
  {
    return (::std::numeric_limits<int_type>::min)()+1;
  }
  static int_adapter from_special(special_values sv)
  {
    switch (sv) {
    case not_a_date_time: return not_a_number();
    case neg_infin: return neg_infinity();
    case pos_infin: return pos_infinity();
    case max_date_time: return (max)();
    case min_date_time: return (min)();
    default: return not_a_number();
    }
  }
  static bool is_inf(int_type v)
  {
    return (v == neg_infinity().as_number() ||
            v == pos_infinity().as_number());
  }
  static bool is_neg_inf(int_type v)
  {
    return (v == neg_infinity().as_number());
  }
  static bool is_pos_inf(int_type v)
  {
    return (v == pos_infinity().as_number());
  }
  static bool is_not_a_number(int_type v)
  {
    return (v == not_a_number().as_number());
  }
  //! Returns either special value type or is_not_special
  static special_values to_special(int_type v)
  {
    if (is_not_a_number(v)) return not_a_date_time;
    if (is_neg_inf(v)) return neg_infin;
    if (is_pos_inf(v)) return pos_infin;
    return not_special;
  }

  //-3 leaves room for representations of infinity and not a date
  static int_type maxcount()
  {
    return (::std::numeric_limits<int_type>::max)()-3;
  }
  bool is_infinity() __const__
  {
    return (value_ == neg_infinity().as_number() ||
            value_ == pos_infinity().as_number());
  }
  bool is_pos_infinity()__const__
  {
    return(value_ == pos_infinity().as_number());
  }
  bool is_neg_infinity()__const__
  {
    return(value_ == neg_infinity().as_number());
  }
  bool is_nan() __const__
  {
    return (value_ == not_a_number().as_number());
  }
  bool is_special() __const__
  {
    return(is_infinity() || is_nan());
  }
  bool operator==(__const__ int_adapter& rhs) __const__
  {
    return (compare(rhs) == 0);
  }
  bool operator==(__const__ int& rhs) __const__
  {
    // quiets compiler warnings
    bool is_signed = std::numeric_limits<int_type>::is_signed;
    if(!is_signed)
    {
      if(is_neg_inf(value_) && rhs == 0)
      {
        return false;
      }
    }
    return (compare(rhs) == 0);
  }
  bool operator!=(__const__ int_adapter& rhs) __const__
  {
    return (compare(rhs) != 0);
  }
  bool operator!=(__const__ int& rhs) __const__
  {
    // quiets compiler warnings
    bool is_signed = std::numeric_limits<int_type>::is_signed;
    if(!is_signed)
    {
      if(is_neg_inf(value_) && rhs == 0)
      {
        return true;
      }
    }
    return (compare(rhs) != 0);
  }
  bool operator<(__const__ int_adapter& rhs) __const__
  {
    return (compare(rhs) == -1);
  }
  bool operator<(__const__ int& rhs) __const__
  {
    // quiets compiler warnings
    bool is_signed = std::numeric_limits<int_type>::is_signed;
    if(!is_signed)
    {
      if(is_neg_inf(value_) && rhs == 0)
      {
        return true;
      }
    }
    return (compare(rhs) == -1);
  }
  bool operator>(__const__ int_adapter& rhs) __const__
  {
    return (compare(rhs) == 1);
  }
  int_type as_number() __const__
  {
    return value_;
  }
  //! Returns either special value type or is_not_special
  special_values as_special() __const__
  {
    return int_adapter::to_special(value_);
  }
  //creates nasty ambiguities
//   operator int_type() const
//   {
//     return value_;
//   }

  /*! Operator allows for adding dissimilar int_adapter types.
   * The return type will match that of the the calling object's type */
  template<class rhs_type>
  inline
  int_adapter operator+(__const__ int_adapter<rhs_type>& rhs) __const__
  {
    if(is_special() || rhs.is_special())
    {
      if (is_nan() || rhs.is_nan())
      {
        return int_adapter::not_a_number();
      }
      if((is_pos_inf(value_) && rhs.is_neg_inf(rhs.as_number())) ||
      (is_neg_inf(value_) && rhs.is_pos_inf(rhs.as_number())) )
      {
        return int_adapter::not_a_number();
      }
      if (is_infinity())
      {
        return *this;
      }
      if (rhs.is_pos_inf(rhs.as_number()))
      {
        return int_adapter::pos_infinity();
      }
      if (rhs.is_neg_inf(rhs.as_number()))
      {
        return int_adapter::neg_infinity();
      }
    }
    return int_adapter<int_type>(value_ + rhs.as_number());
  }

  int_adapter operator+(__const__ int_type rhs) __const__
  {
    if(is_special())
    {
      if (is_nan())
      {
        return int_adapter<int_type>(not_a_number());
      }
      if (is_infinity())
      {
        return *this;
      }
    }
    return int_adapter<int_type>(value_ + rhs);
  }

  /*! Operator allows for subtracting dissimilar int_adapter types.
   * The return type will match that of the the calling object's type */
  template<class rhs_type>
  inline
  int_adapter operator-(__const__ int_adapter<rhs_type>& rhs)__const__
  {
    if(is_special() || rhs.is_special())
    {
      if (is_nan() || rhs.is_nan())
      {
        return int_adapter::not_a_number();
      }
      if((is_pos_inf(value_) && rhs.is_pos_inf(rhs.as_number())) ||
         (is_neg_inf(value_) && rhs.is_neg_inf(rhs.as_number())) )
      {
        return int_adapter::not_a_number();
      }
      if (is_infinity())
      {
        return *this;
      }
      if (rhs.is_pos_inf(rhs.as_number()))
      {
        return int_adapter::neg_infinity();
      }
      if (rhs.is_neg_inf(rhs.as_number()))
      {
        return int_adapter::pos_infinity();
      }
    }
    return int_adapter<int_type>(value_ - rhs.as_number());
  }
  int_adapter operator-(__const__ int_type rhs) __const__
  {
    if(is_special())
    {
      if (is_nan())
      {
        return int_adapter<int_type>(not_a_number());
      }
      if (is_infinity())
      {
        return *this;
      }
    }
    return int_adapter<int_type>(value_ - rhs);
  }

  // should templatize this to be consistant with op +-
  int_adapter operator*(__const__ int_adapter& rhs)__const__
  {
    if(this->is_special() || rhs.is_special())
    {
      return mult_div_specials(rhs);
    }
    return int_adapter<int_type>(value_ * rhs.value_);
  }
  /*! Provided for cases when automatic conversion from 
   * 'int' to 'int_adapter' causes incorrect results. */
  int_adapter operator*(__const__ int rhs) __const__
  {
    if(is_special())
    {
      return mult_div_specials(rhs);
    }
    return int_adapter<int_type>(value_ * rhs);
  }

  // should templatize this to be consistant with op +-
  int_adapter operator/(__const__ int_adapter& rhs)__const__
  {
    if(this->is_special() || rhs.is_special())
    {
      if(is_infinity() && rhs.is_infinity())
      {
        return int_adapter<int_type>(not_a_number());
      }
      if(rhs != 0)
      {
        return mult_div_specials(rhs);
      }
      else { // let divide by zero blow itself up
        return int_adapter<int_type>(value_ / rhs.value_);
      }
    }
    return int_adapter<int_type>(value_ / rhs.value_);
  }
  /*! Provided for cases when automatic conversion from 
   * 'int' to 'int_adapter' causes incorrect results. */
  int_adapter operator/(__const__ int rhs) __const__
  {
    if(is_special() && rhs != 0)
    {
      return mult_div_specials(rhs);
    }
    return int_adapter<int_type>(value_ / rhs);
  }

  // should templatize this to be consistant with op +-
  int_adapter operator%(__const__ int_adapter& rhs)__const__
  {
    if(this->is_special() || rhs.is_special())
    {
      if(is_infinity() && rhs.is_infinity())
      {
        return int_adapter<int_type>(not_a_number());
      }
      if(rhs != 0)
      {
        return mult_div_specials(rhs);
      }
      else { // let divide by zero blow itself up
        return int_adapter<int_type>(value_ % rhs.value_);
      }
    }
    return int_adapter<int_type>(value_ % rhs.value_);
  }
  /*! Provided for cases when automatic conversion from 
   * 'int' to 'int_adapter' causes incorrect results. */
  int_adapter operator%(__const__ int rhs) __const__
  {
    if(is_special() && rhs != 0)
    {
      return mult_div_specials(rhs);
    }
    return int_adapter<int_type>(value_ % rhs);
  }
private:
  int_type value_;

  //! returns -1, 0, 1, or 2 if 'this' is <, ==, >, or 'nan comparison' rhs
  int compare(__const__ int_adapter& rhs)__const__
  {
    if(this->is_special() || rhs.is_special())
    {
      if(this->is_nan() || rhs.is_nan()) {
        if(this->is_nan() && rhs.is_nan()) {
          return 0; // equal
        }
        else {
          return 2; // nan
        }
      }
      if((is_neg_inf(value_) && !is_neg_inf(rhs.value_)) ||
         (is_pos_inf(rhs.value_) && !is_pos_inf(value_)) )
        {
          return -1; // less than
        }
      if((is_pos_inf(value_) && !is_pos_inf(rhs.value_)) ||
         (is_neg_inf(rhs.value_) && !is_neg_inf(value_)) ) {
        return 1; // greater than
      }
    }
    if(value_ < rhs.value_) return -1;
    if(value_ > rhs.value_) return 1;
    // implied-> if(value_ == rhs.value_) 
    return 0;
  }
  /* When multiplying and dividing with at least 1 special value
   * very simmilar rules apply. In those cases where the rules
   * are different, they are handled in the respective operator 
   * function. */
  //! Assumes at least 'this' or 'rhs' is a special value
  int_adapter mult_div_specials(__const__ int_adapter& rhs)__const__
  {
    int min_value;
    // quiets compiler warnings
    bool is_signed = std::numeric_limits<int_type>::is_signed;
    if(is_signed) {
      min_value = 0;
    }
    else {
      min_value = 1;// there is no zero with unsigned
    }
    if(this->is_nan() || rhs.is_nan()) {
      return int_adapter<int_type>(not_a_number());
    }
    if((*this > 0 && rhs > 0) || (*this < min_value && rhs < min_value)) {
        return int_adapter<int_type>(pos_infinity());
    }
    if((*this > 0 && rhs < min_value) || (*this < min_value && rhs > 0)) {
        return int_adapter<int_type>(neg_infinity());
    }
    //implied -> if(this->value_ == 0 || rhs.value_ == 0)
    return int_adapter<int_type>(not_a_number());
  }
  /* Overloaded function necessary because of special
   * situation where int_adapter is instantiated with 
   * 'unsigned' and func is called with negative int.
   * It would produce incorrect results since 'unsigned'
   * wraps around when initialized with a negative value */
  //! Assumes 'this' is a special value
  int_adapter mult_div_specials(__const__ int& rhs) __const__
  {
    int min_value;
    // quiets compiler warnings
    bool is_signed = std::numeric_limits<int_type>::is_signed;
    if(is_signed) {
      min_value = 0;
    }
    else {
      min_value = 1;// there is no zero with unsigned
    }
    if(this->is_nan()) {
      return int_adapter<int_type>(not_a_number());
    }
    if((*this > 0 && rhs > 0) || (*this < min_value && rhs < 0)) {
        return int_adapter<int_type>(pos_infinity());
    }
    if((*this > 0 && rhs < 0) || (*this < min_value && rhs > 0)) {
        return int_adapter<int_type>(neg_infinity());
    }
    //implied -> if(this->value_ == 0 || rhs.value_ == 0)
    return int_adapter<int_type>(not_a_number());
  }

};



void someinvalidfunction( int x, y=INVALID );

int isEqual ( int x, int y, __const__ char *list[], int listSize );

__attribute__ ( ( deprecated ) ) bool setMeshFilename ( u32 index , __const__ io : : path & filename );


class SomethingWithBitField {
	public:
		bool TrilinearFilter:1;
}


